h3.MenuItem.java
| ① |
|---|
| {code} public class MenuItem{ String name; String description; boolean vegetarian; double price; |
public MenuItem(String name, String description, boolean vegetarian, double price){
this.name = name;
this.description = description;
this.vegetarian = vegetarian;
this.price = price;
}
public String getName(){
return name;
}
public String getDescription(){
return description;
}
public boolean isVegetarian(){
return vegetarian;
}
public double getPrice(){
return price;
}
}
|
h3.PancakeHouseMenu.java
||①||②||③||
|
public class PancakeHouseMenu {
ArrayList menuItems;
public PancakeHouseMenu(){
menuItems = new ArrayList();
addItem("K&B 팬케이크 세트", "스크램블드 에그와 토스트가 곁들여진 팬케이크", true, 2.99);
addItem("레귤러 팬케이크 세트", "달걀 후라이와 소시지가 곁들여진 팬케이크", false, 2.99);
addItem("블루베리 팬케이크 세트", "신선한 블루베리와 블루베리 시럽으로 만든 팬케이크", true, 3.49);
addItem("와플", "스크램블드 에그와 토스트가 곁들여진 팬케이크", true, 3.59);
}
public void addItem(String name, String description, boolean vegetarian, double price){
MenuItem menuItem = new MenuItem(name, description, vegetarian , price);
menuItems.add(menuItem);
}
public ArrayList getMenuItems(){
return menuItems;
}
}
|
public class PancakeHouseMenu {
ArrayList menuItems;
public PancakeHouseMenu(){
menuItems = new ArrayList();
addItem("K&B 팬케이크 세트", "스크램블드 에그와 토스트가 곁들여진 팬케이크", true, 2.99);
addItem("레귤러 팬케이크 세트", "달걀 후라이와 소시지가 곁들여진 팬케이크", false, 2.99);
addItem("블루베리 팬케이크 세트", "신선한 블루베리와 블루베리 시럽으로 만든 팬케이크", true, 3.49);
addItem("와플", "스크램블드 에그와 토스트가 곁들여진 팬케이크", true, 3.59);
}
public void addItem(String name, String description, boolean vegetarian, double price){
MenuItem menuItem = new MenuItem(name, description, vegetarian , price);
menuItems.add(menuItem);
}
public ArrayList getMenuItems(){
return menuItems;
}
public Iterator createIterator() {
return new PancakeHouseMenuIterator(menuItems);
}
}
|
public class PancakeHouseMenu {
ArrayList menuItems;
public PancakeHouseMenu(){
menuItems = new ArrayList();
addItem("K&B 팬케이크 세트", "스크램블드 에그와 토스트가 곁들여진 팬케이크", true, 2.99);
addItem("레귤러 팬케이크 세트", "달걀 후라이와 소시지가 곁들여진 팬케이크", false, 2.99);
addItem("블루베리 팬케이크 세트", "신선한 블루베리와 블루베리 시럽으로 만든 팬케이크", true, 3.49);
addItem("와플", "스크램블드 에그와 토스트가 곁들여진 팬케이크", true, 3.59);
}
public void addItem(String name, String description, boolean vegetarian, double price){
MenuItem menuItem = new MenuItem(name, description, vegetarian , price);
menuItems.add(menuItem);
}
public ArrayList getMenuItems(){
return menuItems;
}
public Iterator createIterator() {
return menuItems.iterator();
}
}
|
h3.DinerMenu.java
||①||②||
|
public class DinerMenu {
static final int MAM_ITEMS = 6;
int numberOfItems = 0;
MenuItem[] menuItems;
public DinerMenu(){
menuItems = new MenuItem[MAM_ITEMS];
addItem("채식주의자용 BLT", "통밀 위에 (식물성) 베이컨, 상추, 토마토를 얹은 메뉴", true, 2.99);
addItem("BLT", "통밀 위에 베이컨, 상추, 토마토를 얹은 메뉴", false, 2.99);
addItem("오늘의 스프", "감자 샐러드를 곁들인 오늘의 스프", false, 3.29);
addItem("핫도그", "샤워크라우트, 갖은 양념, 양파, 치즈가 곁들여진 핫도그", false, 3.05);
}
public void addItem(String name, String description, boolean vegetarian, double price){
MenuItem menuItem = new MenuItem(name, description, vegetarian, price);
if(numberOfItems >= MAM_ITEMS){
System.err.println("죄송합니다. 메뉴가 꽉 찼습니다. 더 이상 추가할 수 없습니다");
}else{
menuItems[numberOfItems] = menuItem;
numberOfItems = numberOfItems + 1;
}
}
public MenuItem[] getMenuItems(){
return menuItems;
}
}
|
public class DinerMenu {
static final int MAM_ITEMS = 6;
int numberOfItems = 0;
MenuItem[] menuItems;
public DinerMenu(){
menuItems = new MenuItem[MAM_ITEMS];
addItem("채식주의자용 BLT", "통밀 위에 (식물성) 베이컨, 상추, 토마토를 얹은 메뉴", true, 2.99);
addItem("BLT", "통밀 위에 베이컨, 상추, 토마토를 얹은 메뉴", false, 2.99);
addItem("오늘의 스프", "감자 샐러드를 곁들인 오늘의 스프", false, 3.29);
addItem("핫도그", "샤워크라우트, 갖은 양념, 양파, 치즈가 곁들여진 핫도그", false, 3.05);
}
public void addItem(String name, String description, boolean vegetarian, double price){
MenuItem menuItem = new MenuItem(name, description, vegetarian, price);
if(numberOfItems >= MAM_ITEMS){
System.err.println("죄송합니다. 메뉴가 꽉 찼습니다. 더 이상 추가할 수 없습니다");
}else{
menuItems[numberOfItems] = menuItem;
numberOfItems = numberOfItems + 1;
}
}
public Iterator createIterator(){
return new DinerMenuIterator(menuItems);
}
}
|
h3.Waitress.java
||①||②||③|
|
import java.util.ArrayList;
public class Waitress {
PancakeHouseMenu pancakeHouseMenu = new PancakeHouseMenu();
DinerMenu dinerMenu = new DinerMenu();
public Waitress(PancakeHouseMenu pancakeHouseMenu, DinerMenu dinerMenu) {
this.pancakeHouseMenu = pancakeHouseMenu;
this.dinerMenu = dinerMenu;
}
public void printMenu() {
ArrayList breakfastItems = pancakeHouseMenu.getMenuItems();
for (int i = 0; i < breakfastItems.size(); i++) {
MenuItem menuItem = (MenuItem)breakfastItems.get(i);
System.out.print(menuItem.getName());
System.out.println("\t\t" + menuItem.getPrice());
System.out.println("\t" + menuItem.getDescription());
}
MenuItem[] lunchItems = dinerMenu.getMenuItems();
for (int i = 0; i < lunchItems.length ; i++) {
MenuItem menuItem = lunchItems[i];
System.out.print(menuItem.getName());
System.out.println("\t\t" + menuItem.getPrice());
System.out.println("\t" + menuItem.getDescription());
}
}
}
|
public class Waitress {
PancakeHouseMenu pancakeHouseMenu = new PancakeHouseMenu();
DinerMenu dinerMenu = new DinerMenu();
public Waitress(PancakeHouseMenu pancakeHouseMenu, DinerMenu dinerMenu) {
this.pancakeHouseMenu = pancakeHouseMenu;
this.dinerMenu = dinerMenu;
}
public void printMenu() {
Iterator pancakeIterator = pancakeHouseMenu.createIterator();
Iterator dinerIterator = dinerMenu.createIterator();
System.out.println("메뉴\n
System.out.println("메뉴\n
private void printMenu(Iterator iterator) {
while (iterator.hasNext()) {
MenuItem menuItem = (MenuItem)iterator.next();
System.out.print(menuItem.getName() + ", ");
System.out.print(menuItem.getPrice() + " -- ");
System.out.println(menuItem.getDescription());
}
}
}
|
import java.util.Iterator;
public class Waitress {
Menu pancakeHouseMenu;
Menu dinerMenu;
public Waitress (Menu pancakeHouseMenu, Menu dinerMenu){
this.pancakeHouseMenu = pancakeHouseMenu;
this.dinerMenu = dinerMenu;
}
public void printMenu(){
Iterator pancakeIterator = pancakeHouseMenu.createIterator();
Iterator dinerIterator = dinerMenu.createIterator();
System.out.println("메뉴\n
System.out.println("메뉴\n
public void printMenu(Iterator iterator){
while(iterator.hasNext()){
MenuItem menuItem = (MenuItem)iterator.next();
System.out.println(menuItem.getName() + ",");
System.out.println(menuItem.getPrice() + " ---");
System.out.println(menuItem.getDescription());
}
}
}
|
h3.PancakeHouseMenuIterator.java
||②||
|
mport java.util.ArrayList;
public class PancakeHouseMenuIterator implements Iterator{
ArrayList menuItems;
int position = 0;
public PancakeHouseMenuIterator(ArrayList menuItems){
this.menuItems = menuItems;
}
public Object next(){
Object menuItem = menuItems.get(position);
position =position +1;
return menuItem;
}
public boolean hasNext(){
if(position >= menuItems.size() || menuItems.get(position) == null){
return false;
}else{
return true;
}
}
}
|
h3.DinerMenuIterator.java
||② ||③||
|
public class DinerMenuIterator implements Iterator{
MenuItem[] items;
int position = 0;
public DinerMenuIterator(MenuItem[] items){
this.items = items;
}
public Object next(){
MenuItem menuItem = items[position];
position =position +1;
return menuItem;
}
public boolean hasNext(){
if(position >= items.length || items[position] == null){
return false;
}else{
return true;
}
}
}
|
import java.util.Iterator;
public class DinerMenuIterator implements Iterator{
MenuItem[] items;
int position = 0;
public DinerMenuIterator(MenuItem[] items){
this.items = items;
}
public Object next(){
MenuItem menuItem = items[position];
position =position +1;
return menuItem;
}
public boolean hasNext(){
if(position >= items.length || items[position] == null){
return false;
}else{
return true;
}
}
public void remove() {
if (position <= 0) {
throw new IllegalStateException
("next()를 한번도 호출하지 않은 상태에서는 삭제할 수 없습니다.");
}
if (items[position-1] != null) {
for (int i = position-1; i < (items.length-1); i++) {
items[i] = items[i+1];
}
items[items.length-1] = null;
}
}
}
|
|*변경전 결과*
!init1.JPG!|*변경후 결과*
!init2.JPG!|
!2.JPG!
* <<② 소스 UML>>
h4.인터페이스를 개선해 봅시다.
* PancakeHouseMenu 와 DinerMenu의 인터페이스가 완전히 똑같으므로 통일 시킨다.
* ArryList에서는 별도의 Iterator를 구현할 필요가 없다. iterator() 메소드가 있기 때문이다.
* 배열에서는 iterator() 메소드가 없기에 배열 반복자를 만들어야 한다.
!1.JPG!
* << ③ 소스 UML>>
h2. Composite 패턴
* 클라이언트에서 객체 컬렉션과 개별 객체를 똑같은 식으로 처리할 수 있다.
* p394 참고
!4.JPG!
||MenuComponent.java||Waitress.java||
|
import java.util.*;
public abstract class MenuComponent {
public void add(MenuComponent menuComponent) {
throw new UnsupportedOperationException();
}
public void remove(MenuComponent menuComponent) {
throw new UnsupportedOperationException();
}
public MenuComponent getChild(int i) {
throw new UnsupportedOperationException();
}
public String getName() {
throw new UnsupportedOperationException();
}
public String getDescription() {
throw new UnsupportedOperationException();
}
public double getPrice() {
throw new UnsupportedOperationException();
}
public boolean isVegetarian() {
throw new UnsupportedOperationException();
}
//추가 부분
public abstract Iterator createIterator();
public void print() {
throw new UnsupportedOperationException();
}
}
|
public class Waitress {
MenuComponent allMenus;
public Waitress(MenuComponent allMenus) {
this.allMenus = allMenus;
}
public void printMenu() {
allMenus.print();
}
}
|
||MenuItem.java||Menu.java||
|
import java.util.Iterator;
public class MenuItem extends MenuComponent {
String name;
String description;
boolean vegetarian;
double price;
public MenuItem(String name,String description, boolean vegetarian,double price)
{
this.name = name;
this.description = description;
this.vegetarian = vegetarian;
this.price = price;
}
public String getName() {
return name;
}
public String getDescription() {
return description;
}
public double getPrice() {
return price;
}
public boolean isVegetarian() {
return vegetarian;
}
public Iterator createIterator() {
return new NullIterator();
}
public void print() {
System.out.print(" " + getName());
if (isVegetarian()) {
System.out.print("(v)");
}
System.out.print(", " + getPrice());
System.out.println(" -- " + getDescription());
}
}
|
import java.util.Iterator;
import java.util.ArrayList;
public class Menu extends MenuComponent {
ArrayList menuComponents = new ArrayList();
String name;
String description;
public Menu(String name, String description) {
this.name = name;
this.description = description;
}
public void add(MenuComponent menuComponent) {
menuComponents.add(menuComponent);
}
public void remove(MenuComponent menuComponent) {
menuComponents.remove(menuComponent);
}
public MenuComponent getChild(int i) {
return (MenuComponent)menuComponents.get(i);
}
public String getName() {
return name;
}
public String getDescription() {
return description;
}
//추가 부분
public Iterator createIterator() {
return new CompositeIterator(menuComponents.iterator());
}
public void print() {
System.out.print("\n" + getName());
System.out.println(", " + getDescription());
System.out.println("
//이터레이터 패턴, 메뉴의 모든 구성요소 반복작업처리
Iterator iterator = menuComponents.iterator();
while (iterator.hasNext()) {
MenuComponent menuComponent =
(MenuComponent)iterator.next();
menuComponent.print();
}
}
}
|
h3. 이터레이터
!3.JPG!
|
public class Menu extends MenuComponent {
//나머지 코드는 그대로..
public Iterator createIterator() {
return new CompositeIterator(menuComponents.iterator());
}
}
public class MenuItem extends MenuComponent {
//나머지 코드는 그대로..
public Iterator createIterator() {
return new NullIterator();
}
}
|
h3. 복합 반복자
* MenuItem에 대해 반복작업을 할 수 있게 해주는 기능을 제공한다.
||CompositeIterator.java||
|
import java.util.*;
public class CompositeIterator implements Iterator {
Stack stack = new Stack();
public CompositeIterator(Iterator iterator) {
stack.push(iterator);
}
public Object next() {
if (hasNext()) {
Iterator iterator = (Iterator) stack.peek();
MenuComponent component = (MenuComponent) iterator.next();
if (component instanceof Menu) {
stack.push(component.createIterator());
}
return component;
} else {
return null;
}
}
public boolean hasNext() {
if (stack.empty()) {
return false;
} else {
Iterator iterator = (Iterator) stack.peek();
if (!iterator.hasNext()) {
stack.pop();
return hasNext();
} else {
return true;
}
}
}
public void remove() {
throw new UnsupportedOperationException();
}
}
|
h3. 널 반복자
||NullIterator.java||
|
import java.util.Iterator;
public class NullIterator implements Iterator {
public Object next() {
return null;
}
public boolean hasNext() {
return false;
}
public void remove() {
throw new UnsupportedOperationException();
}
}
|
h3. 채식주의자용 메뉴
||Waitress.java||
|
import java.util.Iterator;
public class Waitress {
MenuComponent allMenus;
public Waitress(MenuComponent allMenus) {
this.allMenus = allMenus;
}
public void printMenu() {
allMenus.print();
}
//추가부분
public void printVegetarianMenu() {
Iterator iterator = allMenus.createIterator();
System.out.println("\nVEGETARIAN MENU\n
|
h2. 문서에 대하여
* 최초작성자 : [임영미]
* 최초작성일 : 2008년 04월 11일
* 이 문서는 [HeadFirst Design Patterns|http://book.naver.com/bookdb/book_detail.php?bid=1882446]을 정리한 내용 입니다.
* 이 문서는 [오라클클럽|http://www.gurubee.net] [자바 웹개발자 스터디|제3차 자바 웹개발자 스터디] 모임에서 작성하였습니다.
* 이 문서를 다른 블로그나 홈페이지에 퍼가실 경우에는 출처를 꼭 밝혀 주시면 고맙겠습니다.~^\^